home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BCI NET
/
BCI NET Dec 94.iso
/
archives
/
programming
/
source
/
tsmorph30s.lha
/
TSM30s.lha
/
RenderSub.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-23
|
25KB
|
972 lines
// TSMorph - Amiga Morphing program
// Copyright (C) © 1993 Topicsave Limited
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// mpaddock@cix.compulink.co.uk
/* Amiga headers */
#define INTUI_V36_NAMES_ONLY
#define INTUITION_IOBSOLETE_H
// Include correct math library
#ifdef MY68881
#include <m68881.h>
extern int rand(void);
#else
#ifdef MY68881_6
#include <math.h>
#include <m68881.h>
#define floor(d) __builtin_fpc(0x0003,d)
#else
#include <math.h>
#endif
#endif
// prevent inclusion of another math library
#define LIBRARIES_MATHFFP_H
// other headers, define some non 2.02 header stuff
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#ifndef PGA_NewLook
#define PGA_NewLook (PGA_Dummy + 0x000A)
#endif
#include <intuition/imageclass.h>
#include <intuition/icclass.h>
#include <devices/input.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <libraries/gadtools.h>
#ifndef GTMN_FullMenu
#define GTMN_FullMenu GT_TagBase+62
#endif
#include <libraries/asl.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/layers_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/input_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/asl_protos.h>
#include <clib/utility_protos.h>
#include <clib/alib_protos.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/layers_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/input_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/asl_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <proto/diskfont.h>
#include <proto/icon.h>
#include <devices/timer.h>
#include <clib/timer_protos.h>
#include <pragmas/timer_pragmas.h>
#include <clib/alib_protos.h>
#include <rexx/errors.h>
#include <pragmas/rexxsyslib_pragmas.h>
#include <clib/rexxsyslib_protos.h>
#include <libraries/amigaguide.h>
#include <clib/amigaguide_protos.h>
#include <pragmas/amigaguide_pragmas.h>
#include <libraries/reqtools.h>
#include <clib/reqtools_protos.h>
#include <pragmas/reqtools.h>
#include <opal/opallib.h>
#include <libraries/dctv.h>
#include <clib/dctv_protos.h>
#include <pragmas/dctv_pragmas.h>
#include <libraries/nofrag.h>
#include <clib/nofrag_protos.h>
#ifdef LIBRARIES_NOFRAG_H
#undef LIBRARIES_NOFRAG_H
#endif
#include <pragmas/nofrag_pragmas.h>
#ifndef LIBRARIES_NOFRAG_H
#define LIBRARIES_NOFRAG_H 1
#endif
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Below is not in the 2.02 version of clib/utility_protos.h
pragmas/utility_pragmas.h */
#if INCLUDE_VERSION < 37
LONG Stricmp(UBYTE *string1,UBYTE *string2);
#pragma libcall UtilityBase Stricmp A2 9802
#endif
// IFF header
#include "iffp/ILBMapp.h"
// Progress requester
#include "progress.h"
// JPEG load stuff
#include "JPEG_LS/jinclude.h"
/* Wait pointer */
static USHORT __chip BusyPointerData[] =
{
0x0000,0x0000,
0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,0x0000,0x07E0,
0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,0x3FF8,0x7FFE,
0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,0x0000,0x07E0,
0x0000,0x0000,
};
// Libraries
extern struct ExecBase *SysBase;
extern struct DosLibrary *DOSBase;
extern struct IntuitionBase *IntuitionBase;
extern struct Library *GfxBase, *LayersBase, *IFFParseBase;
extern struct Library *GadToolsBase, *AslBase, *UtilityBase;
extern struct Library *RexxSysBase;
extern struct Library *AmigaGuideBase;
extern struct Library *TimerBase;
extern struct Library *ReqToolsBase;
extern struct Library *DCTVBase;
extern struct NoFragBase *NoFragBase;
extern struct OpalBase *OpalBase;
// Help stuff
extern AMIGAGUIDECONTEXT handle;
extern struct NewAmigaGuide nag;
extern ULONG ASig;
// nofrag.library stuff
extern struct MemoryChain *Chain;
#define MAXMEM 1000
#define H_Help 10
#define H_Library 11
#define H_ESave 12
#define H_AllocVec 13
#define H_OpenPoints 14
#define H_Progress 15
#define H_AllocPlanes 16
#define H_24 17
#define H_Load 18
#define H_AllocIFF 19
#define H_AllocILBM 20
#define H_FileFormat 21
#define H_SizeMatch 22
#define H_Range 23
#define H_MemPointsR 24
#define H_CloseFile 25
#define H_3Points 26
#define H_Open 27
#define H_ARexx 28
#define H_Really 29
#define HE_OldFormat 30
#define HE_OpalVision 31
#define HE_NoOpal 32
// 24 bitplane bitmap
struct MyBitMap {
struct BitMap BitMap;
PLANEPTR xplanes[16];
};
extern char FileName[256]; // File name buffer
extern long OVQuality; // OpalVision JPG quality
extern BOOL OVFast; // OpalVision fast format IFF
extern BOOL OVThumb; // OpalVision Thumbail
extern BOOL HAM6;
extern BOOL HAM8;
extern BOOL BW16;
extern BOOL BW256;
extern BOOL DCTV3;
extern BOOL DCTV4;
extern UBYTE *arrayr, // Pointers to red,green and blue
*arrayg,
*arrayb;
extern BOOL PPM; // PPM save ?
extern UBYTE *p[3];// chunky pointers - order for OpalVision
#define RED p[0]
#define BLUE p[2]
#define GREEN p[1]
extern UWORD swidth; // scaled width (in full words)
extern struct RastPort RP, // Work Rast Ports
TRP;
extern struct MyBitMap MyBitMap; // Real bit map
extern PLANEPTR Planes[24]; // Bit planes
extern BOOL CreateIcons;// Create Icons on pictures?
extern struct OpalScreen *OScrn;
extern char *OVFormat; // Format of OpalVision save JPG or IFF (or anything) default
extern USHORT width, height, pwidth, pheight, pmode;
extern UBYTE *plane0; // Planes for temporary bit maps
extern UBYTE *plane1;
extern UBYTE *plane2;
extern UBYTE *plane3;
extern UBYTE *plane4;
extern UBYTE *plane5;
extern UBYTE *plane6;
extern UBYTE *plane7;
extern char AnimName[]; // Buffer for file name to save
// Table of parameters
extern struct {
LONG xf; // Current frame
LONG xFrames; // Number of frames
LONG xSingle; // Warp or Morph
LONG xmove; // Movement 1 to 2
LONG xr; // red of image 1
LONG xg; // green
LONG xb; // blue
LONG xr2; // red of image 2
LONG xg2; // green
LONG xb2; // blue
LONG xDo; // Produce this image
LONG xrplus; // Add red
LONG xgplus; // green
LONG xbplus; // blue
LONG xrminus; // subtract red
LONG xgminus; // subtract green
LONG xbminus; // subtract blue
LONG xDX; // X skip
LONG xDY; // Y skip
LONG xStart; // Start Frame number
LONG FILLER[32]; // Filler for future expansion
} Arexx;
#define f Arexx.xf
#define Frames Arexx.xFrames
#define Single Arexx.xSingle
#define move Arexx.xmove
#define r Arexx.xr
#define g Arexx.xg
#define b Arexx.xb
#define r2 Arexx.xr2
#define g2 Arexx.xg2
#define b2 Arexx.xb2
#define Do Arexx.xDo
#define rplus Arexx.xrplus
#define gplus Arexx.xgplus
#define bplus Arexx.xbplus
#define rminus Arexx.xrminus
#define gminus Arexx.xgminus
#define bminus Arexx.xbminus
#define DX Arexx.xDX
#define DY Arexx.xDY
#define Start Arexx.xStart
extern char buffer[256];
extern char buffer1[512];
extern char *Postscript;// ARexx postscript
extern WORD x,y; // Current coords
void help(ULONG hnum);
void DisableWindow(void);
void EnableWindow(void);
void AddMessage(UBYTE *message);
// SaveHAMetc.c
BOOL SaveBW16(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
BOOL SaveBW256(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
BOOL SaveHAM6(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
BOOL SaveHAM8(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
BOOL SaveDCTV(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
/* Frame clicked - irrelevant */
int
FrameClicked(void) {
return 1;
}
/* Line clicked - irrelevant */
int
LineClicked(void) {
return 1;
}
/* Routine for when Stop clicked */
int
StopClicked(void) {
struct EasyStruct EasyStruct = {
sizeof(struct EasyStruct),
0,
NULL,
NULL,
NULL,
};
UBYTE *title = "TSMorph-render";
UBYTE *body = "Really quit?";
struct Window *req;
UBYTE *gad;
ULONG ret = 2;
struct AmigaGuideMsg *agm;
ULONG signals;
struct rtHandlerInfo *rth;
// Disable the window, display a requester and reenable the window
DisableWindow();
if (ReqToolsBase) {
if (handle) {
gad = "_Quit|_Help|_Continue";
}
else {
gad = "_Quit|_Continue";
}
while (ret == 2) {
ret = CALL_HANDLER;
if (rtEZRequestTags(body,gad,NULL,NULL,
RT_ReqHandler, &rth,
RT_Window, ProgressWnd,
RT_Underscore, '_',
RTEZ_ReqTitle, title,
TAG_END) == CALL_HANDLER) {
while (ret == CALL_HANDLER) {
if (!rth->DoNotWait) {
signals = Wait(rth->WaitMask | ASig);
}
ret = rtReqHandlerA(rth,signals,NULL);
if (ret == 2) {
help(H_Really);
}
if (signals & ASig) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
}
else {
ret = 0;
}
}
}
else {
EasyStruct.es_TextFormat = body;
EasyStruct.es_Title = title;
if (handle) {
EasyStruct.es_GadgetFormat = "Quit|Help|Continue";
}
else {
EasyStruct.es_GadgetFormat = "Quit|Continue";
}
req = BuildEasyRequest(ProgressWnd,&EasyStruct,NULL,NULL);
while ((ret = SysReqHandler(req,NULL,TRUE)) == 2) {
help(H_Really);
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
FreeSysRequest(req);
}
EnableWindow();
return !ret;
}
/* Disables the Progress window
* Disables the 'Stop' gadget and displays a wait pointer
*/
void
DisableWindow(void) {
if (ProgressWnd) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Stop],ProgressWnd,NULL,GA_Disabled,TRUE,TAG_END);
SetPointer(ProgressWnd, BusyPointerData, 16, 16, -6, 0);
}
}
/* Enables the Progress window
* Enables the 'Stop' gadget and clears the pointer
*/
void
EnableWindow(void) {
if (ProgressWnd) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Stop],ProgressWnd,NULL,GA_Disabled,FALSE,TAG_END);
ClearPointer(ProgressWnd);
}
}
APTR
MyAllocVec(ULONG size,ULONG requirements) {
ULONG *MyMem;
if (Chain && (size < MAXMEM)) {
if (MyMem = AllocVecItem(Chain,size+4,requirements)) {
*MyMem = size;
return ++MyMem;
}
else {
return NULL;
}
}
else {
if (MyMem = AllocVec(size+4,requirements)) {
*MyMem = size;
return ++MyMem;
}
else {
return NULL;
}
}
}
void MyFreeVec(APTR memptr) {
ULONG *MyMem;
MyMem = memptr;
--MyMem;
if (Chain && (*MyMem < MAXMEM)) {
FreeVecItem(Chain,MyMem);
}
else {
FreeVec(MyMem);
}
}
APTR
MyAllocMem(ULONG size,ULONG requirements) {
ULONG *MyMem;
if (Chain && (size < MAXMEM)) {
if (MyMem = AllocItem(Chain,size+4,requirements)) {
*MyMem = size;
return ++MyMem;
}
else {
return NULL;
}
}
else {
if (MyMem = AllocMem(size+4,requirements)) {
*MyMem = size;
return ++MyMem;
}
else {
return NULL;
}
}
}
void MyFreeMem(APTR memptr,ULONG size) {
ULONG *MyMem;
MyMem = memptr;
--MyMem;
if (Chain && (*MyMem < MAXMEM)) {
FreeItem(Chain,MyMem,size+4);
}
else {
FreeMem(MyMem,size+4);
}
}
// Note no free() is needed
APTR
Mymalloc(ULONG size) {
if (Chain && (size < MAXMEM)) {
return AllocItem(Chain,size,0);
}
else {
return malloc(size);
}
}
APTR
Mystrdup(UBYTE *str) {
UBYTE *t;
if (t = Mymalloc(strlen(str)+1)) {
strcpy(t,str);
}
else {
return NULL;
}
}
/* Display an error message
* ErrorMessage : The main text
* Gadget : Text for one gadget
* extra : more of the text
* helpnum : Number of a help node
*
* See the TSMorph source code for more of how this actually works
*/
void
Error(char *ErrorMessage,char *Gadget,char *extra,ULONG helpnum) {
struct EasyStruct EasyStruct = {
sizeof(struct EasyStruct),
0,
NULL,
NULL,
NULL
};
UBYTE *title = "TSMorph-render Error";
struct Window *req;
UBYTE gad[32] = "Help|";
UBYTE gad1[32] = "_Help|_";
ULONG ret = CALL_HANDLER;
struct AmigaGuideMsg *agm;
ULONG signals;
struct rtHandlerInfo *rth;
// Disable the window and display the requester
DisableWindow();
if (ReqToolsBase) {
if (!handle) {
strcpy(gad1,"_");
}
strcat(gad1,Gadget);
while (ret) {
ret = CALL_HANDLER;
if (rtEZRequestTags(ErrorMessage,gad1,NULL,&extra,
RT_ReqHandler, &rth,
RT_Window, ProgressWnd,
RT_Underscore, '_',
RTEZ_ReqTitle, title,
TAG_END) == CALL_HANDLER) {
while (ret == CALL_HANDLER) {
if (!rth->DoNotWait) {
signals = Wait(rth->WaitMask | ASig);
}
ret = rtReqHandlerA(rth,signals,NULL);
if (ret == 1) {
help(helpnum);
}
if (signals & ASig) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
}
else {
ret = 0;
}
}
}
else {
EasyStruct.es_TextFormat = ErrorMessage;
EasyStruct.es_Title = title;
if (handle) {
strcat(gad,Gadget);
}
else {
strcpy(gad,Gadget);
}
EasyStruct.es_GadgetFormat = gad;
req = BuildEasyRequest(ProgressWnd,&EasyStruct,NULL,extra);
while (ret) {
signals = Wait((1L << req->UserPort->mp_SigBit) | ASig);
if (signals & (1L << req->UserPort->mp_SigBit)) {
ret = SysReqHandler(req,NULL,FALSE);
if (ret == 1) {
help(helpnum);
}
}
if (signals & ASig) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
FreeSysRequest(req);
}
EnableWindow();
}
/* Tries to execute a Rexx script
* msgtxt = name of script
* IgnoreError = TRUE then do not display error message
* Returns: error message
*/
LONG
SendRxMsg(char *msgtxt,BOOL IgnoreError) {
struct MsgPort *reply_port;
struct MsgPort *rx_port;
struct RexxMsg *rx_msg;
LONG ret = RC_FATAL;
if (reply_port = CreateMsgPort()) {
if (rx_msg = CreateRexxMsg(reply_port,"TSM","REXX")) {
rx_msg->rm_Args[0] = msgtxt;
if (FillRexxMsg(rx_msg,1,0)) {
rx_msg->rm_Action = RXCOMM;
Forbid();
if (rx_port = (struct MsgPort *)FindPort("REXX")) {
PutMsg(rx_port, (struct Message *)rx_msg);
Permit();
WaitPort(reply_port);
ReplyMsg(GetMsg(reply_port));
ret = rx_msg->rm_Result1;
}
else {
Permit();
}
ClearRexxMsg(rx_msg, 1);
}
DeleteRexxMsg(rx_msg);
}
DeleteMsgPort(reply_port);
}
// Display an error message (if required)
if (!IgnoreError && ret) {
Error("Error sending ARexx message\n'%s'","Quit",msgtxt,H_ARexx);
}
return ret;
}
/* Handle 'Help' key */
int
ProgressRawKey(void) {
switch (ProgressMsg.Code) {
case 0x5f:
help(H_Help);
}
return 1;
}
// save an image
BOOL
SaveFile(void) {
struct ILBMInfo *ilbm; // IFF stuff to save
BPTR fh; // File handle for PPM
BOOL OkFlag = TRUE;
struct BitMap TBM; // Temp bit map
struct DiskObject *MyDiskObject; // The Icon
char *iconname; // iconname
char *iconname1; // alternate iconname
if (!PPM) {
// Not PPM
if (OVFormat) {
// OpalVision so convert RGB to OpalVision
RGBtoOV(OScrn,p,0,0,swidth,height);
}
else {
// Set up BitMap
InitBitMap(&MyBitMap,(DCTV3?3:((DCTV4|BW16)?4:(HAM6?6:((HAM8|BW256)?8:24)))),width,height);
InitRastPort(&RP);
RP.BitMap = &MyBitMap;
InitRastPort(&TRP);
InitBitMap(&TBM,(DCTV3?3:((DCTV4|BW16)?4:(HAM6?6:((HAM8|BW256)?8:8)))),width,1);
TBM.BytesPerRow = (((width+15)>>4)<<1);
TBM.Rows = 1;
TRP.BitMap = &TBM;
TBM.Planes[0]=plane0;
TBM.Planes[1]=plane1;
TBM.Planes[2]=plane2;
TBM.Planes[3]=plane3;
TBM.Planes[4]=plane4;
TBM.Planes[5]=plane5;
TBM.Planes[6]=plane6;
TBM.Planes[7]=plane7;
if (!HAM6 && !HAM8 && !BW16 && !BW256 && !DCTV3 && !DCTV4) {
// i.e. 24 bit ILBM?
// so convert chunky to planar
MyBitMap.BitMap.Depth = 8;
MyBitMap.BitMap.Planes[0] = Planes[0];
MyBitMap.BitMap.Planes[1] = Planes[1];
MyBitMap.BitMap.Planes[2] = Planes[2];
MyBitMap.BitMap.Planes[3] = Planes[3];
MyBitMap.BitMap.Planes[4] = Planes[4];
MyBitMap.BitMap.Planes[5] = Planes[5];
MyBitMap.BitMap.Planes[6] = Planes[6];
MyBitMap.BitMap.Planes[7] = Planes[7];
WritePixelArray8(&RP,0,0,width-1,height-1,RED,&TRP);
WaitBlit();
MyBitMap.BitMap.Planes[0] = Planes[8];
MyBitMap.BitMap.Planes[1] = Planes[9];
MyBitMap.BitMap.Planes[2] = Planes[10];
MyBitMap.BitMap.Planes[3] = Planes[11];
MyBitMap.BitMap.Planes[4] = Planes[12];
MyBitMap.BitMap.Planes[5] = Planes[13];
MyBitMap.BitMap.Planes[6] = Planes[14];
MyBitMap.BitMap.Planes[7] = Planes[15];
WritePixelArray8(&RP,0,0,width-1,height-1,GREEN,&TRP);
WaitBlit();
MyBitMap.BitMap.Planes[0] = Planes[16];
MyBitMap.BitMap.Planes[1] = Planes[17];
MyBitMap.BitMap.Planes[2] = Planes[18];
MyBitMap.BitMap.Planes[3] = Planes[19];
MyBitMap.BitMap.Planes[4] = Planes[20];
MyBitMap.BitMap.Planes[5] = Planes[21];
MyBitMap.BitMap.Planes[6] = Planes[22];
MyBitMap.BitMap.Planes[7] = Planes[23];
WritePixelArray8(&RP,0,0,width-1,height-1,BLUE,&TRP);
WaitBlit();
}
// Reset up BitMap
MyBitMap.BitMap.Depth = (DCTV3?3:((DCTV4|BW16)?4:(HAM6?6:((HAM8|BW256)?8:24))));
MyBitMap.BitMap.Planes[0] = Planes[0];
MyBitMap.BitMap.Planes[1] = Planes[1];
MyBitMap.BitMap.Planes[2] = Planes[2];
MyBitMap.BitMap.Planes[3] = Planes[3];
MyBitMap.BitMap.Planes[4] = Planes[4];
MyBitMap.BitMap.Planes[5] = Planes[5];
MyBitMap.BitMap.Planes[6] = Planes[6];
MyBitMap.BitMap.Planes[7] = Planes[7];
MyBitMap.BitMap.Planes[8] = Planes[8];
MyBitMap.BitMap.Planes[9] = Planes[9];
MyBitMap.BitMap.Planes[10] = Planes[10];
MyBitMap.BitMap.Planes[11] = Planes[11];
MyBitMap.BitMap.Planes[12] = Planes[12];
MyBitMap.BitMap.Planes[13] = Planes[13];
MyBitMap.BitMap.Planes[14] = Planes[14];
MyBitMap.BitMap.Planes[15] = Planes[15];
MyBitMap.BitMap.Planes[16] = Planes[16];
MyBitMap.BitMap.Planes[17] = Planes[17];
MyBitMap.BitMap.Planes[18] = Planes[18];
MyBitMap.BitMap.Planes[19] = Planes[19];
MyBitMap.BitMap.Planes[20] = Planes[20];
MyBitMap.BitMap.Planes[21] = Planes[21];
MyBitMap.BitMap.Planes[22] = Planes[22];
MyBitMap.BitMap.Planes[23] = Planes[23];
}
}
// Set up output file name
sprintf(FileName,AnimName,f+Start-1);
if (PPM) {
// PPM Save is very simple P6 mode
AddMessage("Saving PPM image");
if (fh = Open(FileName,MODE_NEWFILE)) {
sprintf(buffer,"P6\n%ld %ld\n255\n",width,height);
FPuts(fh,buffer);
arrayr=RED;
arrayg=GREEN;
arrayb=BLUE;
// loop thru lines
for (y=0;
(y<height) && OkFlag;
y++) {
// Loop thru columns
for (x=0;
x < width;
x++) {
FPutC(fh,*arrayr);
FPutC(fh,*arrayg);
FPutC(fh,*arrayb);
arrayr++;
arrayg++;
arrayb++;
}
// skip part word at end of line
arrayr += (swidth - width);
arrayg += (swidth - width);
arrayb += (swidth - width);
}
if (!Close(fh)) {
OkFlag = FALSE;
}
}
else {
OkFlag = FALSE;
}
}
else {
// Save non PPM
if (OVFormat) {
// Save OpalVision
if (!strcmp(OVFormat,"JPG")) {
AddMessage("Saving Opal JPEG image");
// Save JPEG
OkFlag = !SaveJPEG24(OScrn,FileName,(OVThumb?0:NOTHUMBNAIL),OVQuality);
}
else {
AddMessage("Saving Opal IFF24 image");
// Save IFF
OkFlag = !SaveIFF24(OScrn,FileName,NULL,(OVThumb?0:NOTHUMBNAIL)|(OVFast?OVFASTFORMAT:0));
}
}
else {
if (HAM6) {
AddMessage("Saving HAM6 image");
OkFlag = SaveHAM6(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
if (HAM8) {
AddMessage("Saving HAM8 image");
OkFlag = SaveHAM8(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
if (BW16) {
AddMessage("Saving BW16 image");
OkFlag = SaveBW16(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
if (BW256) {
AddMessage("Saving BW256 image");
OkFlag = SaveBW256(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
if (DCTV3 || DCTV4) {
AddMessage(DCTV3?"Saving DCTV3 image":"Saving DCTV4 image");
OkFlag = SaveDCTV(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
AddMessage("Saving ILBM24 image");
// allocate some IFF stuff
if (ilbm = (struct ILBMInfo *)MyAllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
if (ilbm->ParseInfo.iff = AllocIFF()) {
OkFlag = !saveilbm(ilbm, &MyBitMap, pmode,
width, height, pwidth, pheight,
NULL, 0, 0, /* colortable */
mskNone, 0, /* masking, transparent */
NULL, NULL, /* chunklists */
FileName);
// Close everything down cleanly
FreeIFF(ilbm->ParseInfo.iff);
}
else {
OkFlag = FALSE;
}
MyFreeMem(ilbm,sizeof(struct ILBMInfo));
}
else {
OkFlag = FALSE;
}
}
}
}
}
}
}
}
if (OkFlag) {
if (CreateIcons) {
// try to save an Icon
if (MyDiskObject = GetDiskObject(FileName)) {
// Do not overwrite if already present
FreeDiskObject(MyDiskObject);
}
else {
// Set up two possible names
if (OVFormat) {
if (!strcmp(OVFormat,"JPG")) {
iconname = "ENV:TSMorph/def_jpg";
iconname1 = "ENV:SYS/def_jpg";
}
else {
iconname = "ENV:TSMorph/def_iff";
iconname1 = "ENV:SYS/def_iff";
}
}
else {
if (PPM) {
iconname = "ENV:TSMorph/def_ppm";
iconname1 = "ENV:SYS/def_ppm";
}
else {
if (BW16) {
iconname = "ENV:TSMorph/def_bw16";
iconname1 = "ENV:SYS/def_bw16";
}
else {
if (BW256) {
iconname = "ENV:TSMorph/def_bw256";
iconname1 = "ENV:SYS/def_bw256";
}
else {
if (HAM6) {
iconname = "ENV:TSMorph/def_ham6";
iconname1 = "ENV:SYS/def_ham6";
}
else {
if (HAM8) {
iconname = "ENV:TSMorph/def_ham8";
iconname1 = "ENV:SYS/def_ham8";
}
else {
if (DCTV3) {
iconname = "ENV:TSMorph/def_dctv3";
iconname1 = "ENV:SYS/def_dctv3";
}
else {
if (DCTV4) {
iconname = "ENV:TSMorph/def_dctv4";
iconname1 = "ENV:SYS/def_dctv4";
}
else {
iconname = "ENV:TSMorph/def_ilbm";
iconname1 = "ENV:SYS/def_ilbm";
}
}
}
}
}
}
}
}
// Try two names, as last resort use default project
if ((MyDiskObject = GetDiskObject(iconname)) ||
(MyDiskObject = GetDiskObject(iconname1)) ||
(MyDiskObject = GetDefDiskObject(WBPROJECT))) {
PutDiskObject(FileName,MyDiskObject);
FreeDiskObject(MyDiskObject);
}
}
}
}
if (!OkFlag) {
Error("Error saving file '%s'","Quit",FileName,H_ESave);
}
else {
// Post image processing
if (strcmp(Postscript,"OFF")) {
strcpy(buffer,Postscript);
strcat(buffer," %ld %ld %ld %s");
sprintf(buffer1,buffer,f+Start-1,Frames,Single,FileName);
AddMessage("Postscript processing");
OkFlag = !SendRxMsg(buffer1,FALSE);
}
}
return OkFlag;
}